package models

import (
	"fmt"
	"strconv"

	"go.uber.org/zap"
)

type GetUserRequest struct {
	Name     string `json:"name" `
	Account  string `json:"account"`
	Age      int    `json:"age" `
	PageNum  int    `json:"pageNum" `
	PageSize int    `json:"pageSize" `
}

type GetUserResponse struct {
	Total    int     `json:"total"`
	UserList []*User `json:"items"`
}

type AuthUser struct {
	Account  string `json:"account"`
	Password string `json:"password" `
}

// User 用户表 model 定义
type User struct {
	Id       int    `db:"id"`
	UserId   string `db:"user_id"`
	Account  string `db:"account"`
	Name     string `db:"name" binding:"required"`
	Age      int    `db:"age" binding:"required,gte=1,lte=130"`
	Password string `db:"password" `
	Email    string `db:"email" binding:"required"`
	Status   int    `db:"status" binding:"required"`
}

type UserPrimary struct {
	Id int `db:"id" binding:"required"`
}

// InsertOne 新增用户
func (user *User) InsertOne() (userId string, err error) {
	var queryParam = GetUserRequest{Account: user.Account}
	if res, queryErr := FindUserList(&queryParam); queryErr != nil {
		return "", queryErr
	} else {
		if res.Total > 0 {
			return "", fmt.Errorf("该账户已存在")
		}
	}

	insertSql := `insert into user (user_id, name, account, age, password, email, status) values (?,?,?,?,?,?,?)`
	_, err = wConn.Exec(insertSql,
		user.UserId,
		user.Name,
		user.Account,
		user.Age,
		user.Password,
		user.Email,
		user.Status)
	userId = user.UserId
	if err != nil {
		return "", err
	}
	return userId, err
}

// FindOne 查询用户详情
func (user *User) FindOne() (*User, error) {
	var userList []*User
	err := rConn.Select(&userList, ` select * from user where id = ? limit 1 `, user.Id)
	fmt.Println("FindOne", err)
	if err != nil {
		return nil, err
	}
	if len(userList) > 0 {
		return userList[0], nil
	}
	return nil, nil
}

// UpdateOne 修改用户
func (user *User) UpdateOne() (*User, error) {
	updateSql := ` update user set name = ?,age = ?,email = ?,status = ? where id = ? `
	_, err := wConn.Exec(updateSql,
		user.Name,
		user.Age,
		user.Email,
		user.Status,
		user.Id)
	if err != nil {
		return nil, err
	}
	var updateUser *User
	updateUser, err = user.FindOne()
	if err != nil {
		return nil, err
	}
	return updateUser, nil
}

// DeleteOne 删除用户
func (user *User) DeleteOne() (err error) {
	var isDelete *User
	isDelete, err = user.FindOne()
	if err != nil {
		fmt.Println(err)
		return err
	}
	if isDelete == nil {
		return fmt.Errorf("该用户已被删除")
	}
	if isDelete.Id > 0 {
		deleteSql := `delete from user where id = ?`
		_, err = wConn.Exec(deleteSql, isDelete.Id)
		if err != nil {
			return err
		}
	}
	return nil
}

// FindUserList 获取分页用户列表
func FindUserList(condition *GetUserRequest) (res GetUserResponse, err error) {
	pageNum := 1
	pageSize := 10
	start := (pageNum - 1) * pageSize
	var userList []*User
	querySql := ` select * from user where 1=1 `
	if condition.Name != "" {
		querySql += ` and name like "%` + condition.Name + `%" `
	}
	if condition.Account != "" {
		querySql += ` and account = "` + condition.Account + `"`
	}
	if condition.Age > 0 {
		querySql += ` and age = ` + strconv.Itoa(condition.Age)
	}
	querySql += ` limit ?,? `

	if condition.PageNum > 0 {
		pageNum = condition.PageNum
	}
	if condition.PageSize > 0 {
		pageSize = condition.PageSize
	}
	fmt.Println("执行sql", querySql)
	err = rConn.Select(&userList,
		querySql,
		strconv.Itoa(start),
		strconv.Itoa(pageSize))
	if err != nil {
		fmt.Println("sql error", err)
		return res, nil
	}
	res.Total = len(userList)
	res.UserList = userList
	return res, nil
}

// QuerySubscribeUser 查询存量订阅用户
func QuerySubscribeUser() (users []*User) {
	sqlStr := "select * from user where status = ?"
	err := rConn.Select(&users, sqlStr, 1)
	if err != nil {
		zap.L().Error("QuerySubscribeUser failed, err: ", zap.Error(err))
		return nil
	}
	zap.L().Info("查询存量订阅用户数据", zap.Any("users", users))
	return
}

// BatchInsert 批量新增用户
func BatchInsert(users []*User) error {
	_, err := wConn.NamedExec("INSERT INTO user (user_id, name, email, password, status, age) VALUES (:user_id, :name, :email, :password, :status, :age)", users)
	if err != nil {
		return err
	}
	return nil
}
